﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Data;
using System.Xml;
using System.Data.SqlTypes;
using DTO = Microsoft.MSE.Catalog.Contracts;

namespace Microsoft.MSE.Catalog.Module.Data
{
    public class SoapFault 
    {
        public static void CreateSoapFault(DTO.SoapFault fault, Guid operationVersionID, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[CreateSoapFaultForOperationVersion]";

            try
            {
                if (conn == null) conn = CatalogSvcHelper.GetConnection();
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter OperationVersionIDParam = new SqlParameter("@OperationVersionID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);
                    SqlParameter ActionParam = new SqlParameter("@Action", SqlDbType.NVarChar, 256);
                    SqlParameter ProtectionLevelParam = new SqlParameter("@ProtectionLevel", SqlDbType.NVarChar, 32);
                    SqlParameter SchemaObjectIDParam = new SqlParameter("@SchemaObjectID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;

                    IDParam.Direction = ParameterDirection.Output;
                    OperationVersionIDParam.Value = operationVersionID;
                    NameParam.Value = fault.Name;
                    SchemaObjectIDParam.Value = fault.SchemaObject.ID;
                    if (((Guid)SchemaObjectIDParam.Value) == Guid.Empty)
                    {
                        throw new ApplicationException("Attempt to create message fault with invalid SchemaObject");
                    }
                    ActionParam.Value = fault.Action;
                    ProtectionLevelParam.Value = fault.ProtectionLevel.ToString();

                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(OperationVersionIDParam);
                    cmd.Parameters.Add(NameParam);
                    cmd.Parameters.Add(SchemaObjectIDParam);
                    cmd.Parameters.Add(ActionParam);
                    cmd.Parameters.Add(ProtectionLevelParam);

                    cmd.ExecuteNonQuery();
                    ID = (Guid)IDParam.Value;
                    fault.ID = ID;
                }

            }
            finally
            {
                if (autoclose && (conn != null)) conn.Close(); //Close connection if opened in this method
            }
        }

        public static void DeleteSoapFaults(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[DeleteSoapFaultsForOperationVersion]";

            try
            {
                if (conn == null) conn = CatalogSvcHelper.GetConnection();
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@OperationVersionID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    cmd.ExecuteNonQuery();
                }

            }
            finally
            {
                if (autoclose && (conn != null)) conn.Close(); //Close connection if opened in this method
            }
        }

        public static void DeleteSoapFault(Guid ID, Guid soapFaultID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[DeleteSoapFaultForOperationVersion]";

            try
            {
                if (conn == null) conn = CatalogSvcHelper.GetConnection();
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter FaultIDParam = new SqlParameter("@SoapFaultID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    FaultIDParam.Value = soapFaultID;
                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(FaultIDParam);

                    cmd.ExecuteNonQuery();
                }

            }
            finally
            {
                if (autoclose && (conn != null)) conn.Close(); //Close connection if opened in this method
            }
        }

        public static List<DTO.SoapFault> GetSoapFaults(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            List<DTO.SoapFault> soapFaults = new List<DTO.SoapFault>();
            const string sprocname = "[ServiceEngine].[GetSoapFaultsForOperationVersion]";

            try
            {
                if (conn == null) conn = CatalogSvcHelper.GetConnection();
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@OperationVersionID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            while (reader.Read())
                            {
                                DTO.SoapFault fault = new DTO.SoapFault();
                                fault.ID = reader.GetGuid(0);
                                fault.Name = reader.GetString(1);
                                fault.Action = reader.GetString(2);
                                fault.ProtectionLevel = (System.Net.Security.ProtectionLevel)Enum.Parse(typeof(System.Net.Security.ProtectionLevel), reader.GetString(3));
                                fault.SchemaObject = SchemaObject.GetSchemaObject(reader.GetGuid(4),txn,conn);
                                soapFaults.Add(fault);
                            }
                        }
                    }
                }
            }
            finally
            {
                if (autoclose && (conn != null)) conn.Close(); //Close connection if opened in this method
            }

            return soapFaults;

        }
    }
}
